#include "StyleMgr.h"
#include "FileSys.h"
#include "Utility.h"
#include <map>
#include <QFileInfo>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QFileSystemWatcher>

class ResourceHolder
{
public:
	ResourceHolder() = default;
	void init(StyleMgr::StyleType style);
	void loadColors(StyleMgr::StyleType style);
	void setDftSize();

	QColor color(const QString& crName);
	int size(const QString& sizeName);
	void changeStyle(StyleMgr::StyleType style);

	void loadColorFromFile(const QString& cfgPath);
private:
	std::map<QString, QColor>	m_colors;
	std::map<QString, int>	m_sizes;
};

void ResourceHolder::init(StyleMgr::StyleType style)
{
	loadColors(style);
	setDftSize();
}

void ResourceHolder::loadColors(StyleMgr::StyleType style)
{
	QString cfgFilePath = style == StyleMgr::StyleType::kDefault ? ":/res/colors.cfg" : ":/res/colors_white.cfg";
	loadColorFromFile(cfgFilePath);
	cfgFilePath = FileSys::instance()->appCfgDir();
	if (style == StyleMgr::StyleType::kDefault)
		cfgFilePath.append("/colors.cfg");
	else
		cfgFilePath.append("/colors_white.cfg");
	loadColorFromFile(cfgFilePath);
}

void ResourceHolder::setDftSize()
{
	m_sizes["ButtonWidth"] = 40;
	m_sizes["ButtonHeight"] = 24;
	m_sizes["RoundCorner"] = 4;
	m_sizes["CtrlSpacing"] = 4;
}

QColor ResourceHolder::color(const QString& crName)
{
	auto iter = m_colors.find(crName);
	if (iter != m_colors.end())
		return iter->second;

	Q_ASSERT(false);
	return QColor(Qt::GlobalColor::black);
}

int ResourceHolder::size(const QString& sizeName)
{
	auto iter = m_sizes.find(sizeName);
	if (iter != m_sizes.end())
		return iter->second;

	Q_ASSERT(false);
	return -1;
}

void ResourceHolder::changeStyle(StyleMgr::StyleType style)
{
	m_colors.clear();
	loadColors(style);
}

void ResourceHolder::loadColorFromFile(const QString& cfgPath)
{
	QJsonDocument doc = CoreUtility::openJsonDoc(cfgPath);
	if (doc.isNull())
		return;

	QJsonObject colorObj = doc.object().take("colors").toObject();
	for (auto iter = colorObj.constBegin(); iter != colorObj.constEnd(); ++iter)
	{
		const QString& crKey = iter.key();
		int crValue = iter.value().toString().toInt(nullptr, 16);//TODO异常处理?
		m_colors[crKey] = crValue;
	}
}

StyleMgr& StyleMgr::instance()
{
	static StyleMgr sm;
	return sm;
}

QColor StyleMgr::color(const QString& crName)
{
	return m_res->color(crName);
}

int StyleMgr::size(const QString& sizeName)
{
	return m_res->size(sizeName);
}

void StyleMgr::changeStyle(StyleType style)
{
	if (m_style == style)
		return;
	m_res->changeStyle(style);

	//TODO 通知UI，参考QStyle?
}

QString StyleMgr::appStyleSheet()
{
	static QString s_styleSheet = QStringLiteral(
		"QLineEdit{background-color:#%1;color:#%2;border:1px solid #%3;border-radius:2px}"
		"QLineEdit:hover{background-color:#%4;}"
		"QLineEdit:focus{border:1px solid #%5;color:#%6}"
		"QLineEdit{lineedit-password-character:42;}"
		"QLineEdit:disabled{color:#%11;}"
		"QComboBox QAbstractItemView {border: 1px solid #%7;border-radius:2px;}"
		"QComboBox QAbstractItemView::item {height:24px;}"
		"QPushButton {background-color:#%8;color:#%9;border:none;border-radius:2px;}"
		"QPushButton:disabled{background-color:#%10;color:#%11;}"
		"QPushButton#grey{background-color:#%12;}"
		"QPushButton:hover{background-color:#%13;}"
		"QPushButton:pressed{background-color:#%14;}"
		"QPushButton#grey:hover{background-color:#%13;}"
		"QPushButton#grey:pressed{background-color:#%14;}"
		"QLabel {color:#%2;}"
		"QLabel:disabled {color:#%11;background:transparent;}"
		"QMenu {border:1px solid #%3;background-color:#%1;color:#%2;border-radius:2px;margin:0px;}"
		"QMenu::item:selected{background-color:#%4;}"
		"QToolTip{background-color:#%1;color:#%2;border:1px solid #%4;border-radius:2px;}"
	);

	QString ss = s_styleSheet.arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("BorderNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Hover").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Highlight").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Highlight").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("BorderNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("ButtonNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("ButtonDisable").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("TxtDisabled").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("ButtonDisable").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Hover").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("ButtonPressed").rgb(), 0, 16);

	QFile file(":/widgets/scrollBar.qss");
	bool ret = file.open(QFile::ReadOnly);
	QString str = file.readAll();
	ss += str;

	return ss;
}

StyleMgr::StyleMgr()
{
	m_res = new ResourceHolder();
	m_style = StyleType::kDefault;//Read from configure
	m_res->init(m_style);
}

